import re
from django.contrib.auth import login
# from django.http import response
from django.shortcuts import redirect, render
from django.views import View
from QQLoginTool.QQtool import OAuthQQ
from django.conf import settings
from django import http
from django_redis import get_redis_connection

from carts.utils import merge_cookie_redis_data
from meiduo_mall.utils import sinaweibopy3
from meiduo_mall.utils.my_encrypt import encode_openid, decode_openid
from oauth.models import QQUser, SinaUser
from users.models import User


class QQLoginView(View):
    def get(self, request):
        """
        当用户点击QQ小图标的时候请求获取QQ的登录界面，然后来到了这里
        :param request:
        :return:
        """
        request.GET.get('next', '/')
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI, state=next)
        # 获取QQ登录扫码页面，扫码后得到Authorization
        # Code
        login_url = oauth.get_qq_url()  # 这里通过QQ提供的方法可以得到QQ登录的界面的网址
        return http.JsonResponse({'login_url': login_url})


class OpenIDView(View):
    def get(self, request):
        code = request.GET.get('code')
        if not code:
            return http.HttpResponseForbidden("code丢失")
        oauth = OAuthQQ(client_id=settings.QQ_CLIENT_ID, client_secret=settings.QQ_CLIENT_SECRET,
                        redirect_uri=settings.QQ_REDIRECT_URI, state=next)
        # 获取QQ登录扫码页面，扫码后得到Authorization
        # Code
        # access_token = oauth.get_qq_url(code)
        access_token = oauth.get_access_token(code)
        if not access_token:
            return http.HttpResponseForbidden("access_token丢失")

        openid = oauth.get_open_id(access_token)

        # 查询数据库查询openid有没有绑定
        try:
            qq_user = QQUser.objects.get(openid=openid)
        except Exception as e:
            # 初次授权
            # 待会记得加密
            openid = encode_openid(openid)  # 对QQ的openid进行加密
            return render(request, 'oauth_callback.html', context={'token': openid})

        else:
            # 已经授权
            user = qq_user.user
            login(request, user)

            response = redirect('/')
            response.set_cookie("username", user.username, max_age=3600 * 24 * 2)
            response = merge_cookie_redis_data(request, response)
        return response

        # Create your views here.

    def post(self, request):
        access_token = request.POST.get("access_token")  # openid
        mobile = request.POST.get("mobile")
        pwd = request.POST.get("pwd")
        sms_code = request.POST.get("sms_code")
        access_token = decode_openid(access_token)
        if not access_token:
            return http.HttpResponseForbidden('QQ授权到期，请重新授权登录')

        if not all([access_token, mobile, pwd, sms_code]):
            return http.HttpResponseForbidden('参数不全')

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('手机格式有误')

        redis_conn = get_redis_connection('code')
        redis_sms_code = redis_conn.get("sms_code_%s" % mobile)

        if not redis_sms_code:
            return http.HttpResponseForbidden('短信验证码已过期')
        if redis_sms_code.decode() != sms_code:
            return http.HttpResponseForbidden('短信验证码错误')
        try:
            user = User.objects.get(mobile=mobile)
        except Exception as e:
            user = User.objects.create_user(password=pwd, mobile=mobile, username='meiduo%s' % mobile)
            QQUser.objects.create(user=user, openid=access_token)
            login(request, user)
            response = redirect('/')
            response.set_cookie("username", user.username, max_age=3600 * 24 * 2)
            response = merge_cookie_redis_data(request, response)
            return response
        else:
            if not user.check_password(pwd):
                return http.HttpResponseForbidden('密码错误')
        QQUser.objects.create(user=user, openid=access_token)
        login(request, user)
        response = redirect('/')
        response.set_cookie("username", user.username, max_age=3600 * 24 * 2)
        response = merge_cookie_redis_data(request, response)
        return response


# 微博登录
class WeiboView(View):
    def get(self, request):
        request.GET.get('next', '/')
        client = sinaweibopy3.APIClient(app_key=settings.APP_KEY, app_secret=settings.APP_SECRET,
                                        redirect_uri=settings.REDIRECT_URL)
        login_url = client.get_authorize_url()
        return redirect(login_url)


class WeiboCallback(View):
    def get(self, request):
        code = request.GET.get('code')
        client = sinaweibopy3.APIClient(app_key=settings.APP_KEY, app_secret=settings.APP_SECRET,
                                        redirect_uri=settings.REDIRECT_URL)
        result = client.request_access_token(code)
        access_token = result.access_token
        if not access_token:
            return http.HttpResponseForbidden("access_token丢失")

        # 查询数据库查询openid有没有绑定
        try:
            sina_user = SinaUser.objects.get(uid=access_token)
        except Exception as e:
            # 初次授权
            # 待会记得加密
            uid = encode_openid(access_token)  # 对QQ的openid进行加密
            return render(request, 'oauth_callback.html', context={'token': uid})

        else:
            # 已经授权
            user = sina_user.user
            login(request, user)
            response = redirect('/')
            response.set_cookie("username", user.username, max_age=3600 * 24 * 2)
            response = merge_cookie_redis_data(request, response)
        return response

    def post(self, request):
        access_token = request.POST.get("access_token")  # openid
        mobile = request.POST.get("mobile")
        pwd = request.POST.get("pwd")
        sms_code = request.POST.get("sms_code")
        access_token = decode_openid(access_token)
        if not access_token:
            return http.HttpResponseForbidden('微博授权到期，请重新授权登录')

        if not all([access_token, mobile, pwd, sms_code]):
            return http.HttpResponseForbidden('参数不全')

        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('手机格式有误')

        redis_conn = get_redis_connection('code')
        redis_sms_code = redis_conn.get("sms_code_%s" % mobile)

        if not redis_sms_code:
            return http.HttpResponseForbidden('短信验证码已过期')
        if redis_sms_code.decode() != sms_code:
            return http.HttpResponseForbidden('短信验证码错误')
        try:
            user = User.objects.get(mobile=mobile)
        except Exception as e:
            user = User.objects.create_user(password=pwd, mobile=mobile, username='meiduo%s' % mobile)
            SinaUser.objects.create(user=user, uid=access_token)
            login(request, user)
            response = redirect('/')
            response.set_cookie("username", user.username, max_age=3600 * 24 * 2)
            response = merge_cookie_redis_data(request, response)
            return response
        else:
            if not user.check_password(pwd):
                return http.HttpResponseForbidden('密码错误')
        SinaUser.objects.create(user=user, uid=access_token)
        login(request, user)
        response = redirect('/')
        response.set_cookie("username", user.username, max_age=3600 * 24 * 2)
        response = merge_cookie_redis_data(request, response)
        return response